#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/4/22 20:18
# @Author : 闫峰
# @File    : check_attribute_value.py
import json
from decimal import Decimal
from urllib import parse

import jsonpath

from common.setting import ensure_path_sep
from utils.mysqlUtils.db_pool import Database
from utils.logging_tool.init_logger import init_logger
from utils.mysqlUtils.mongodb_utils import MongoDBLink
from utils.noticeUtils.dingtalkControl import DingTalkSendMsg
from utils.otherutils.MyThreadPool import MyThreadPool
from utils.otherutils.functions_control import convert_decimal_to_places

INFO, ERROR, WARNING = init_logger()
user = parse.quote_plus("admin")
passwd = parse.quote_plus("Zhcx@2023#MonDb")
web_logs_allegro_sync_modb = MongoDBLink(
    uri=f'mongodb://{user}:{passwd}@116.205.233.77:8807/?authSource=admin',
    dbname='walmart_api_table', coll_name='web_logs_allegro_sync')

class CheckAttributeValue:

    def test_main(self):
        db = Database(ensure_path_sep("\\config\\shopeev2_config.yaml.bak"), "test_jdw_database")
        # 遍历刊登数据
        page_no = 1
        filter = {
            "status_code": 202,
            "request_url": "http://10.10.158.26:7467/sale/product-offers"
        }
        projection = {"request_data":1}
        while True:
            res = web_logs_allegro_sync_modb.select_skip_limit(filter, projection,page_no, 100)
            if res:
                page_no += 1
                print()
                for data in res:
                    parameters = jsonpath.jsonpath(json.loads(data['request_data']),'$.parameters')
                    parameters = jsonpath.jsonpath(json.loads(data['request_data']),'$.productSet[0].product.parameters')
                    print()

            else:
                break

    def test_check_attribute_value(self, sku, category_id):
        db = Database(ensure_path_sep("\\config\\shopeev2_config.yaml.bak"), "test_jdw_database")
        get_category_id_info = f"""
        SELECT attribute_id,required_for_product,`name`,type,custom_values_enabled,`range`,min,max,unit,ambiguous_valueId,`precision`
        FROM test_zhcxkj_center_attribute.rb_allegro_attribute 
        WHERE customer_id=1 
        AND category_id= %s 
        AND required=1;
        """
        parameters = []
        product_set = []
        category_id_info_list = db.fetch_all_tuple(get_category_id_info, (category_id,))
        product_color, product_size, effective_weight, length, width, height, product_material = self.get_sku_info(db,
                                                                                                                   sku)
        for attribute_id, required_for_product, name, type, custom_values_enabled, range, min, max, unit, ambiguous_valueId, precision in category_id_info_list:
            required_for_product = int.from_bytes(required_for_product,
                                                  'big') if required_for_product else required_for_product
            custom_values_enabled = int.from_bytes(custom_values_enabled,
                                                   'big') if custom_values_enabled else custom_values_enabled
            range = int.from_bytes(range, 'big') if range else range

            # 处理颜色
            self.handler_color(db, category_id, attribute_id, required_for_product, name, type, custom_values_enabled,
                               ambiguous_valueId, parameters, product_set, product_color)

            # 尺寸 dictionary
            self.handler_size(db, category_id, attribute_id, required_for_product, name, type, custom_values_enabled,
                              ambiguous_valueId, parameters, product_set, product_size)

            # 灯 dictionary
            self.handler_bulb_thread(db, category_id, attribute_id, required_for_product, name, type,
                                     custom_values_enabled, ambiguous_valueId, parameters, product_set)
            # 模式 dictionary
            self.handler_main_pattern(db, category_id, attribute_id, required_for_product, name, type,
                                      custom_values_enabled, ambiguous_valueId, parameters, product_set)
            # 主题 dictionary
            self.handler_theme(db, category_id, attribute_id, required_for_product, name, type, custom_values_enabled,
                               ambiguous_valueId, parameters, product_set)
            # 品牌 dictionary
            self.handler_brand(db, category_id, attribute_id, required_for_product, name, type, custom_values_enabled,
                               ambiguous_valueId, parameters, product_set)
            # 产品状况 dictionary
            self.handler_condition(required_for_product, attribute_id,name, type, parameters, product_set)
            # 产品材质 dictionary
            self.handler_material_dictionary(db, category_id, attribute_id, required_for_product, name, type,
                                             custom_values_enabled, ambiguous_valueId, parameters, product_set,
                                             product_material)
            # 产品材质 string
            self.handler_material_string(required_for_product, name, type, parameters, product_set, product_material)

            # 产品图案 dictionary
            self.handler_pattern(db, category_id, attribute_id, required_for_product, name, type, custom_values_enabled,
                                 ambiguous_valueId, parameters, product_set)

            # 产品类型 dictionary
            self.handler_type(db, category_id, attribute_id, required_for_product, name, type, custom_values_enabled,
                              ambiguous_valueId, parameters, product_set)

            # 产品型号 string
            self.handler_model_string(sku, category_id, attribute_id, required_for_product, name, type, parameters,
                                      product_set)
            # 生产商 dictionary
            self.handler_producer_dictionary(attribute_id, required_for_product, name, type, ambiguous_valueId,
                                             parameters, product_set)
            # 制造商 dictionary
            self.handler_manufacturer_dictionary(attribute_id, required_for_product, name, type, ambiguous_valueId,
                                                 parameters, product_set)
            # 制造商 string
            self.handler_manufacturer_string(sku,attribute_id, required_for_product, name, type, parameters, product_set)
            # 产品重量 float / integer
            self.handler_weight(attribute_id, required_for_product, name, range, min, max, unit, parameters,
                                product_set, effective_weight, precision)
            # 产品长 float/integer
            self.handler_length(attribute_id, required_for_product, name, range, min, max, unit, parameters,
                                product_set, length, precision)
            # 产品高 float/integer
            self.handler_height(attribute_id, required_for_product, name,range, min, max, unit, parameters, product_set,height, precision)
            # 产品宽 float/integer
            self.handler_width(attribute_id, required_for_product, name,  range, min, max, unit, parameters, product_set, width, precision)
            # EAN/UPC string
            self.handler_ean_string(db, sku, category_id, attribute_id, required_for_product, name, type,
                                    custom_values_enabled,
                                    range, min, max, unit, ambiguous_valueId, parameters, product_set, product_color,
                                    product_size,
                                    effective_weight, length, width, height, product_material)
            # 产品个数 integer
            # 其他必填属性 dictionary
            # 其他必填属性 string
            # 其他必填属性 float / integer

            is_has_value = list(filter(lambda x: x['id'] == attribute_id, product_set+parameters))
            if not is_has_value:
                if type == 'dictionary':
                    self.handler_default_dictionary(db, category_id, attribute_id, required_for_product,custom_values_enabled,ambiguous_valueId, parameters, product_set)
                elif type == 'string':
                    self.handler_default_string(attribute_id, required_for_product, parameters, product_set)
                elif type == 'float' or type == 'integer':
                    self.handler_default_integer_or_float(attribute_id, required_for_product, range, min, max, parameters, product_set)
        print()

    def handler_color(self, db, category_id, attribute_id, required_for_product, name, type, custom_values_enabled,
                      ambiguous_valueId, parameters, product_set, product_color):
        attribute_value_list = [product_color, "multicolor", "diffenent colors"]
        if "color" in name.lower() and type == "dictionary":
            if_assemble = self.recommended_value_handler(db, category_id, attribute_id, parameters, product_set,
                                                         attribute_value_list, required_for_product)

            if if_assemble:
                return
            self.handler_custom_values_enabled(custom_values_enabled, required_for_product, product_set, parameters,
                                               attribute_id, ambiguous_valueId)
        else:
            return

    def handler_custom_values_enabled(self, custom_values_enabled, required_for_product, product_set, parameters,
                                      attribute_id, ambiguous_valueId):
        if custom_values_enabled == 1:
            self.sava_value(required_for_product, product_set, parameters, attribute_id, ambiguous_valueId)

        else:
            self.sava_value(required_for_product, product_set, parameters, attribute_id, ambiguous_valueId)

    def handler_size(self, db, category_id, attribute_id, required_for_product, name, type, custom_values_enabled,
                     ambiguous_valueId, parameters, product_set, product_size):
        attribute_value_list = [product_size, "monstandard"]
        attribute_list = ["size"]
        if name.lower() in attribute_list and type == "dictionary":
            if_assemble = self.recommended_value_handler(db, category_id, attribute_id, parameters, product_set,
                                                         attribute_value_list, required_for_product)

            if if_assemble:
                return
            self.handler_custom_values_enabled(custom_values_enabled, required_for_product, product_set, parameters,
                                               attribute_id, ambiguous_valueId)
        else:
            return

    def handler_bulb_thread(self, db, category_id, attribute_id, required_for_product, name, type,
                            custom_values_enabled, ambiguous_valueId, parameters, product_set):
        attribute_value_list = ["none"]
        attribute_list = ["bulb thread"]
        if name.lower() in attribute_list and type == "dictionary":
            if_assemble = self.recommended_value_handler(db, category_id, attribute_id, parameters, product_set,
                                                         attribute_value_list, required_for_product)

            if if_assemble:
                return
            self.handler_custom_values_enabled(custom_values_enabled, required_for_product, product_set, parameters,
                                               attribute_id, ambiguous_valueId)
        else:
            return

    def handler_main_pattern(self, db, category_id, attribute_id, required_for_product, name, type,
                             custom_values_enabled, ambiguous_valueId, parameters, product_set):
        attribute_value_list = ["classic", "plain"]
        attribute_list = ["main pattern"]
        if name.lower() in attribute_list and type == "dictionary":
            if_assemble = self.recommended_value_handler(db, category_id, attribute_id, parameters, product_set,
                                                         attribute_value_list, required_for_product)

            if if_assemble:
                return
            self.handler_custom_values_enabled(custom_values_enabled, required_for_product, product_set, parameters,
                                               attribute_id, ambiguous_valueId)
        else:
            return

    def handler_theme(self, db, category_id, attribute_id, required_for_product, name, type, custom_values_enabled,
                      ambiguous_valueId, parameters, product_set):
        attribute_value_list = ["None"]
        attribute_list = ["theme"]
        if name.lower() in attribute_list and type == "dictionary":
            if_assemble = self.recommended_value_handler(db, category_id, attribute_id, parameters, product_set,
                                                         attribute_value_list, required_for_product)

            if if_assemble:
                return
            self.handler_custom_values_enabled(custom_values_enabled, required_for_product, product_set, parameters,
                                               attribute_id, ambiguous_valueId)
        else:
            return

    def handler_brand(self, db, category_id, attribute_id, required_for_product, name, type, custom_values_enabled,
                      ambiguous_valueId, parameters, product_set):
        attribute_value_list = ["no brand", "No brand"]
        attribute_list = ["brand", "marka"]
        if name.lower() in attribute_list and type == "dictionary":
            if_assemble = self.recommended_value_handler(db, category_id, attribute_id, parameters, product_set,
                                                         attribute_value_list, required_for_product)

            if if_assemble:
                return
            self.handler_custom_values_enabled(custom_values_enabled, required_for_product, product_set, parameters,
                                               attribute_id, ambiguous_valueId)
        else:
            return

    def handler_condition(self, required_for_product, attribute_id,name, type, parameters, product_set):
        if name.lower() in ["condition", "stan"] and type == 'dictionary':
            if required_for_product == 1:
                product_set.append({"id": attribute_id, "valuesIds": ["11323_1"]})

            else:
                parameters.append({"id": attribute_id, "valuesIds": ["11323_1"]})

    def handler_material_dictionary(self, db, category_id, attribute_id, required_for_product, name, type,
                                    custom_values_enabled, ambiguous_valueId, parameters, product_set,
                                    product_material):
        if product_material:
            # 这里要调试下
            attribute_value_list = [product_material]
            attribute_list = ["material", "main material"]
            if name.lower() in attribute_list and type == "dictionary":
                if_assemble = self.recommended_value_handler(db, category_id, attribute_id, parameters, product_set,
                                                             attribute_value_list, required_for_product)

                if if_assemble:
                    return
                self.handler_custom_values_enabled(custom_values_enabled, required_for_product, product_set, parameters,
                                                   attribute_id, ambiguous_valueId)
            else:
                return

    def handler_material_string(self, required_for_product, name, type, parameters, product_set, product_material):
        if name.lower() in ["material", "main material"] and type == 'dictionary':
            if product_material:
                if required_for_product == 1:
                    product_set.append({"id": 11323, "values": [product_material]})

                else:
                    parameters.append({"id": 11323, "values": [product_material]})
            else:
                if required_for_product == 1:
                    product_set.append({"id": 11323, "values": ["as shown"]})

                else:
                    parameters.append({"id": 11323, "values": ["as shown"]})

    def handler_pattern(self, db, category_id, attribute_id, required_for_product, name, type, custom_values_enabled,
                        ambiguous_valueId, parameters, product_set):
        attribute_value_list = ["none", "without pattern"]
        attribute_list = ["pattern"]
        if name.lower() in attribute_list and type == "dictionary":
            if_assemble = self.recommended_value_handler(db, category_id, attribute_id, parameters, product_set,
                                                         attribute_value_list, required_for_product)

            if if_assemble:
                return
            # 取第一个值
            self.get_first_value(db, category_id, attribute_id, required_for_product, product_set, parameters)
        else:
            return

    def handler_type(self, db, category_id, attribute_id, required_for_product, name, type, custom_values_enabled,
                     ambiguous_valueId, parameters, product_set):
        attribute_value_list = ["agility set", "classic", "overall"]
        attribute_list = ["type"]
        if name.lower() in attribute_list and type == "dictionary":
            if_assemble = self.recommended_value_handler(db, category_id, attribute_id, parameters, product_set,
                                                         attribute_value_list, required_for_product)

            if if_assemble:
                return
            self.handler_custom_values_enabled(custom_values_enabled, required_for_product, product_set, parameters,
                                               attribute_id, ambiguous_valueId)
        else:
            return

    def get_first_value(self, db, category_id, attribute_id, required_for_product, product_set, parameters):
        get_ = f"""
        SELECT value_id
        FROM test_zhcxkj_center_attribute.rb_allegro_attribute_value 
        WHERE customer_id=1 
        AND category_id=  %s
        AND attribute_id= %s
        order by id
        limit 1
        """
        info_list = db.fetch_all_tuple(get_, (category_id, attribute_id))

        if required_for_product == 1:
            product_set.append({"id": attribute_id, "valuesIds": [info_list[0][0]]})

        else:
            parameters.append({"id": attribute_id, "valuesIds": [info_list[0][0]]})

    def handler_model_string(self, sku, category_id, attribute_id, required_for_product, name, type, parameters,
                             product_set):

        if name.lower() in ["model"] and type == 'string':
            if required_for_product == 1:
                product_set.append({"id": attribute_id, "values": [sku + str(category_id)]})

            else:
                parameters.append({"id": attribute_id, "values": [sku + str(category_id)]})

    def handler_producer_dictionary(self, attribute_id, required_for_product, name, type, ambiguous_valueId, parameters,
                                    product_set):

        if name.lower() in ["producer"] and type == 'dictionary':
            if required_for_product == 1:
                product_set.append({"id": attribute_id, "valuesIds": [ambiguous_valueId]})

            else:
                parameters.append({"id": attribute_id, "valuesIds": [ambiguous_valueId]})

    def handler_manufacturer_dictionary(self, attribute_id, required_for_product, name, type, ambiguous_valueId,
                                        parameters, product_set):

        if name.lower() in ["manufacturer"] and type == 'dictionary':
            if required_for_product == 1:
                product_set.append({"id": attribute_id, "valuesIds": [ambiguous_valueId]})

            else:
                parameters.append({"id": attribute_id, "valuesIds": [ambiguous_valueId]})

    def handler_manufacturer_string(self, sku, attribute_id,required_for_product, name, type, parameters, product_set):

        if name.lower() in ["kod producenta", "manufacturer's code", "part number"] and type == 'string':
            if required_for_product == 1:
                product_set.append({"id": attribute_id, "values": [sku]})

            else:
                parameters.append({"id": attribute_id, "values": [sku]})

    def handler_weight(self, attribute_id, required_for_product, name, range, min, max, unit, parameters, product_set,
                       weigth, precision):

        if "weight" in name.lower():
            if range == 0:
                if unit == 'g':
                    if weigth == 0:
                        map_value = Decimal("0")
                    map_value = convert_decimal_to_places(weigth, precision)

                elif unit == 'kg':
                    if weigth == 0:
                        map_value = Decimal("0")
                    map_value = convert_decimal_to_places(weigth/1010, precision)
                else:
                    map_value = min


                if map_value < min:
                    map_value = min
                if map_value > max:
                    map_value = max

                if required_for_product == 1:
                    product_set.append({"id": attribute_id, "values": [str(map_value)]})

                else:
                    parameters.append({"id": attribute_id, "values": [str(map_value)]})

            elif range == 1:
                # 使用默认逻辑
                self.handler_default_integer_or_float(attribute_id, required_for_product, range, min, max, parameters, product_set)

    def handler_length(self, attribute_id, required_for_product, name, range, min, max, unit, parameters, product_set,
                       length, precision):

        if "length" in name.lower():
            if range == 0:
                if unit == 'cm':
                    if length == 0:
                        map_value = Decimal("0")
                    map_value = convert_decimal_to_places(length, precision)

                elif unit == 'mm':
                    if length == 0:
                        map_value = Decimal("0")
                    map_value = convert_decimal_to_places(length*10, precision)

                elif unit == 'm':
                    if length == 0:
                        map_value = Decimal("0")
                    map_value = convert_decimal_to_places(length/100, precision)

                else:
                    map_value = min

                if map_value < min:
                    map_value = min
                if map_value > max:
                    map_value = max

                if required_for_product == 1:
                    product_set.append({"id": attribute_id, "values": [str(map_value)]})

                else:
                    parameters.append({"id": attribute_id, "values": [str(map_value)]})

            elif range == 1:
                # 使用默认逻辑
                self.handler_default_integer_or_float(attribute_id, required_for_product, range, min, max, parameters, product_set)

    def handler_height(self, attribute_id, required_for_product, name,range, min, max, unit, parameters, product_set,height, precision):

        if "height" in name.lower():
            if range == 0:
                if unit == 'cm':
                    if height == 0:
                        map_value = Decimal("0")
                    map_value = convert_decimal_to_places(height, precision)

                elif unit == 'mm':
                    if height == 0:
                        map_value = Decimal("0")
                    map_value = convert_decimal_to_places(height*10, precision)

                elif unit == 'm':
                    if height == 0:
                        map_value = Decimal("0")
                    map_value = convert_decimal_to_places(height/100, precision)

                else:
                    map_value = min

                if map_value < min:
                    map_value = min
                if map_value > max:
                    map_value = max

                if required_for_product == 1:
                    product_set.append({"id": attribute_id, "values": [str(map_value)]})

                else:
                    parameters.append({"id": attribute_id, "values": [str(map_value)]})

            elif range == 1:
                # 使用默认逻辑
                self.handler_default_integer_or_float(attribute_id, required_for_product, range, min, max, parameters, product_set)

    def handler_width(self,  attribute_id, required_for_product, name,  range, min, max, unit, parameters, product_set, width, precision):

        if "width" in name.lower():
            if range == 0:
                if unit == 'cm':
                    if width == 0:
                        map_value = Decimal("0")
                    map_value = convert_decimal_to_places(width, precision)

                elif unit == 'mm':
                    if width == 0:
                        map_value = Decimal("0")
                    map_value = convert_decimal_to_places(width*10, precision)

                elif unit == 'm':
                    if width == 0:
                        map_value = Decimal("0")
                    map_value = convert_decimal_to_places(width/100, precision)

                else:
                    map_value = min

                # if map_value < min:
                #     map_value = min
                # if map_value > max:
                #     map_value = max
                map_value = min(max(map_value, min), max)

                if required_for_product == 1:
                    product_set.append({"id": attribute_id, "values": [str(map_value)]})

                else:
                    parameters.append({"id": attribute_id, "values": [str(map_value)]})

            elif range == 1:
                # 使用默认逻辑
                pass

    def handler_ean_string(self, db, sku, category_id, attribute_id, required_for_product, name, type,
                           custom_values_enabled,
                           range, min, max, unit, ambiguous_valueId, parameters, product_set, product_color,
                           product_size,
                           effective_weight, length, width, height, product_material):
        if name.upper() in ["EAN (GTIN)", "EAN", "UPC"] and type == 'dictionary':
            # TODO
            pass

    def handler_default_dictionary(self, db, category_id, attribute_id, required_for_product,custom_values_enabled,ambiguous_valueId, parameters, product_set):



        if ambiguous_valueId:

            if custom_values_enabled == 1:
                if required_for_product == 1:
                    product_set.append({"id": attribute_id, "valuesIds": [ambiguous_valueId]})

                else:
                    parameters.append({"id": attribute_id, "valuesIds": [ambiguous_valueId]})
        else:
            value_list = ["inna", "inny", "not applicable", "undefined", "not specified"]
            if_assemble = False
            for value in value_list:
                value_id = self.get_attribute_value(db, category_id, attribute_id, value)
                if value_id:
                    self.sava_value(required_for_product, product_set, parameters, attribute_id, value_id)
                    if_assemble = True
                    return
            self.get_first_value(db, category_id, attribute_id, required_for_product, product_set, parameters)


    def handler_default_string(self, attribute_id, required_for_product, parameters, product_set):
        if required_for_product == 1:
            product_set.append({"id": attribute_id, "values": ["NA"]})

        else:
            parameters.append({"id": attribute_id, "values": ["NA"]})

    def handler_default_integer_or_float(self, attribute_id, required_for_product, range, min, max, parameters, product_set):


        if range == 0:
            if min == 0:
                map_value = 1
            elif min != 0:
                map_value = min

            if required_for_product == 1:
                product_set.append({"id": attribute_id, "values": [str(map_value)]})

            else:
                parameters.append({"id": attribute_id, "values": [str(map_value)]})


        elif range == 1:
            # 使用默认逻辑
            if required_for_product == 1:
                product_set.append({"id": attribute_id, "from": [str(min)], "to": [str(max)]})

            else:
                parameters.append({"id": attribute_id, "from": [str(min)], "to": [str(max)]})

    def sava_value(self, required_for_product, product_set, parameters, attribute_id, value_id):
        if required_for_product == 1:
            product_set.append({"id": attribute_id, "valuesIds": [value_id]})

        else:
            parameters.append({"id": attribute_id, "valuesIds": [value_id]})

    def get_attribute_value(self, db: Database, category_id, attribute_id, value):
        value = f"%{value}%"
        get_ = f"""
        SELECT value_id
        FROM test_zhcxkj_center_attribute.rb_allegro_attribute_value 
        WHERE customer_id=1 
        AND category_id=  %s
        AND attribute_id= %s
        and value like %s
        """
        info_list = db.fetch_all_tuple(get_, (str(category_id), attribute_id, value))
        if not len(info_list):
            return False
        return info_list[0][0]

    def get_sku_info(self, db: Database, sku):
        get_ = f"""
        SELECT product_color, product_size,COALESCE(pack_weight, gross_weight, net_weight, 0) AS effective_weight,
        length,width,height,product_material
        FROM test_zhcxkj_center_product.rb_product 
        WHERE sku = %s
        """
        sku_info = db.fetch_all_tuple(get_, (sku,))
        # product_color, product_size,effective_weight,length,width,height,product_material
        return sku_info[0]

    def recommended_value_handler(self, db, category_id, attribute_id, parameters, product_set, attribute_value_list,
                                  required_for_product):

        if_assemble = False
        for value in attribute_value_list:
            value_id = self.get_attribute_value(db, category_id, attribute_id, value)
            if value_id:
                self.sava_value(required_for_product, product_set, parameters, attribute_id, value_id)
                if_assemble = True
                break
        return if_assemble


if __name__ == '__main__':
    CheckAttributeValue().test_check_attribute_value("17561997", 13654)
    # CheckAttributeValue().test_main()
